//
// Created by Admin on 2025/10/8.
//
#include <boost/asio.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>

namespace asio = boost::asio;
using asio::ip::tcp;

// 一个连接的生命期由 shared_ptr 管理
class session : public std::enable_shared_from_this<session> {
public:
    session(tcp::socket sock) : socket_(std::move(sock)) {}

    void start() { do_read(); }

private:
    void do_read() {
        auto self = shared_from_this();
        socket_.async_read_some(
            asio::buffer(data_, sizeof(data_)),
            [self](boost::system::error_code ec, std::size_t len) {
              if (!ec) self->do_write(len);
            });
    }

    void do_write(std::size_t len) {
        auto self = shared_from_this();
        asio::async_write(
            socket_, asio::buffer(data_, len),
            [self](boost::system::error_code ec, std::size_t /*bytes*/) {
              if (!ec) self->do_read();
            });
    }

    tcp::socket socket_;
    char data_[1024];  // 零拷贝，复用缓冲
};

void server(unsigned short port) {
    try {
        asio::io_context ioc;
        tcp::acceptor acc(ioc, tcp::endpoint(tcp::v4(), port));

        std::cout << "Boost.Asio echo server listening on " << port << '\n';

        std::function<void()> accept_loop;
        accept_loop = [&]() {
            acc.async_accept(
                [&](boost::system::error_code ec, tcp::socket sock) {
                  if (!ec) {
                    std::make_shared<session>(std::move(sock))->start();
                  }
                  accept_loop();  // 继续接受下一个
                });
        };
        accept_loop();

        ioc.run();  // 单线程事件循环
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}

int main(int argc, char* argv[]) {
    unsigned short port = 7000;
    if (argc > 1) port = static_cast<unsigned short>(std::atoi(argv[1]));
    server(port);
    return 0;
}